/**
 * 
 */
package com.ditty.interceptor;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ditty.annotation.ActionInterceptor;
import com.ditty.kit.LinkedKit;

/**
 * @author dingnate
 *
 */
public final class Interceptors {
	private static final Logger LOG = LoggerFactory.getLogger(Interceptors.class);
	private static final Interceptors ME = new Interceptors();
	private final List<AbstractActionIntercptor> interceptors = new ArrayList<AbstractActionIntercptor>();
	private AbstractActionIntercptor head;

	Interceptors() {
	}

	public static Interceptors me() {
		return ME;
	}

	public synchronized AbstractActionIntercptor buildActionIntercptor() {
		if (head == null) {
			head = LinkedKit.buildLinkedObjects(interceptors, null);
		}
		return head;
	}

	public void addInterceptor(AbstractActionIntercptor interceptor) {
		interceptors.add(interceptor);
	}

	/**
	 * @return the interceptors
	 */
	public final List<AbstractActionIntercptor> getInterceptors() {
		return interceptors;
	}

	/**
	 * @return the head
	 */
	public final AbstractActionIntercptor getHead() {
		if (head == null) {
			head = buildActionIntercptor();
		}
		return head;
	}

	/**
	 * @param head the head to set
	 */
	public final void setHead(AbstractActionIntercptor head) {
		this.head = head;
	}

	public static AbstractActionIntercptor buildControllerInterceptor(Class<?> controllerClass) {
		ActionInterceptor interceptorAnn = controllerClass.getAnnotation(ActionInterceptor.class);
		if (interceptorAnn != null) {
			return buildInterceptor(interceptorAnn.value());
		}
		return null;
	}

	public static AbstractActionIntercptor buildActionInterceptor(Method method) {
		ActionInterceptor interceptorAnn = method.getAnnotation(ActionInterceptor.class);
		if (interceptorAnn != null) {
			return buildInterceptor(interceptorAnn.value());
		}
		return null;
	}

	/**
	 * @param interceptorClasses
	 * @return
	 */
	private static AbstractActionIntercptor buildInterceptor(Class<? extends AbstractActionIntercptor>[] interceptorClasses) {
		AbstractActionIntercptor[] array = new AbstractActionIntercptor[interceptorClasses.length];
		for (int i = 0; i < interceptorClasses.length; i++) {
			try {
				array[i] = interceptorClasses[i].newInstance();
			} catch (Exception e) {
				LOG.error("instance error:" + interceptorClasses[i], e);
			}
		}
		return LinkedKit.buildLinkedObjects(array);
	}
}
